'''
此模块用于处理Excel数据表读取相关的问题。

1.格式化读取的Excel数据表中的columns。
2.删除数据表中的指定列中数据为空的列。
3.列出所有无效的身份证号所在行。
4.自动在data_df数据表的最前面加上自增的索引列。
'''

import pandas as pd
import numpy as np
import datetime
from datatoolsobj.idcard.idcard import id_verify,id_verify_full
from datatoolsobj.excel.excelformat import XlsxWriterFormat

def format_columns(data_df):
    '''读取Excel数据表中的columns，并进行简单的处理。
    1.去掉列表列项标题中的无用空白列。
    2.去掉列表列项标题中的回车。
    data_df:为打开的Excel数据表的DataFrame
    返回：不含空列标题的列表及去掉了回车符号的列标题列表。
    '''
    columns = data_df.columns.tolist()
    columns = [item for item in columns if item.find('Unnamed')]
    new_columns = [item.replace('\n','') for item in columns]
    return columns,new_columns

def drop_na_line(data_df,col_label):
    '''删除给定数据表data_df中的col_label表示的列中数据为空的列。会对原表进行删除操作。
    data_df:要操作的数据表。
    col_label:要操作的数据列标签。
    '''
    na_data = data_df[data_df[col_label].isna()]
    data_df.drop(na_data.index,inplace=True)
    
def find_not_verify_id(data_df,id_label):
    '''获取给定数据表data_df中的id_label表示的身份证号码列中身份证号码无效的数据。
    data_df:要操作的数据表。
    id_label:要操作的身份证号码数据列标签。
    '''
    verify_id_df = data_df[id_label].apply(id_verify)
    return data_df[~verify_id_df]

def get_not_verify_id(data_df,id_label):
    '''获取给定数据表data_df中的id_label表示的身份证号码列中身份证号码无效的数据,并指明错误原因。
    data_df:要操作的数据表。
    id_label:要操作的身份证号码数据列标签。
    '''
    not_verify_df = find_not_verify_id(data_df,id_label).copy()
    not_verify_df.insert(len(not_verify_df.columns),'错误原因','')
    for index,line in not_verify_df.iterrows():
        try:
            idcard = line[id_label]
            id_verify_full(idcard)
        except ValueError as e:
            #print(e)
            not_verify_df.loc[index,['错误原因']] = str(e)
    return not_verify_df


def excel_columns_normaliz(data,label):
    """
    对Excel数据文件中读取的数据列进行规范化处理。
    :param data: DataFrame数据。
    :param label:要处理的数据列名。
    :return:修整后的列数据
    """
    data_columns = data[label].astype('str')
    remove_blank = data_columns.str.replace(r'[,.\s]','',regex=True)
    return remove_blank.replace(r"\n","",regex=True)


def excel_auto_normaliz(data,columns,excel_columns_normaliz_callback=excel_columns_normaliz):
    """
    自动规范化Excel数据表中的Object列。
    :param data:要进行规范化的数据表，DataFrame格式。
    :param columns:要作处理的列名列表。
    :param excel_columns_normaliz_callback:用于进行列规范的回调函数。
    :return:自动规范化后的数据表。
    """
    use_data = data.copy()
    for col in columns:
        index = use_data.columns.tolist().index(col)
        col_dtype = use_data.dtypes.tolist()[index]
        if col_dtype == 'object':
            use_data[col] = excel_columns_normaliz_callback(use_data,col)
    return use_data

def excel_prase_date(excel_date):
    """
    Excel日期格式转换。
    :param excel_date:一个Excel格式的日期。
    :return: 标准的Pandas时间戳。
    """
    if type(excel_date) == str:
        try:
            int_date = int(excel_date)
            if int_date > 2040:
                delta_days = datetime.timedelta(int(excel_date))
                base_date = datetime.datetime(year=1899, month=12, day=30)
                return pd.to_datetime(base_date+delta_days)
            else:
                return pd.to_datetime(excel_date)
        except ValueError:
            return pd.to_datetime(excel_date)
    elif type(excel_date) == int:
        delta_days = datetime.timedelta(int(excel_date))
        base_date = datetime.datetime(year=1899, month=12, day=30)
        return pd.to_datetime(base_date+delta_days)
    elif type(excel_date) == pd.Timestamp:
        return excel_date
    else:
        return pd.to_datetime(excel_date)

def excel_out_file(data,path,title,sheet_names="信息导出",footer=None):
    '''将DataFrame按照统一规范化的方式输出为Excel文件。

    :param data: DataFrame数据帧
    :param path: 要保存的路径
    :param title: Excel文件中标题部分显示内容
    :param sheet_names:  Excel文件Sheet表名称
    :param footer:文件尾部内容
    :return: None
    '''
    out_data = data.copy()
    if '序号' not in out_data.columns:
        out_data.insert(0,'序号',0)
    out_data['序号'] = np.arange(1, len(out_data)+1)
    out_data['备注'] = np.nan
    with XlsxWriterFormat(path) as xw:
        xw.to_excel(out_data,sheetname=sheet_names,title=title,footer=footer)

def excel_out_files(datas,path,title,sheet_names,footers=None):
    '''将DataFrame按照统一规范化的方式输出为Excel文件。支持多Sheet页输出。

    :param data: DataFrame数据帧数组
    :param path: 要保存的路径数据
    :param title: Excel文件中标题部分显示内容数组
    :param sheet_names:  Excel文件Sheet表名称数组
    :param footer:文件尾部内容数组
    :return: None
    '''
    out_datas = []
    for data in datas:
        out_data = data.copy()
        if '序号' not in out_data.columns:
            out_data.insert(0,'序号',0)
        out_data['序号'] = np.arange(1, len(out_data)+1)
        out_data['备注'] = np.nan
        out_datas.append(out_data)
    with XlsxWriterFormat(path) as xw:
        for i,out_data in enumerate(out_datas):
            xw.to_excel(out_datas[i],sheetname=sheet_names[i],title=title[i],footer=footers[i])